package com.salinity.kun.helper;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Properties;

import com.salinity.kun.Constant;
import com.salinity.kun.common.SafeProperties;
import com.salinity.kun.util.StringUtil;

public class ConstantHelper {

	private static SafeProperties BASE_CONFIG;
	private static SafeProperties FS_CONFIG;

	static {
		BASE_CONFIG = new SafeProperties();
		loadProps(BASE_CONFIG, Constant.BASE_CONFIG_PATH);
		FS_CONFIG = new SafeProperties();
		loadProps(FS_CONFIG, Constant.FS_CONFIG_PATH);
	}

	public static String getString(String key) {
		String value = null;
		if (BASE_CONFIG != null) {
			value = getString(key, BASE_CONFIG);
		}
		if (value == null && FS_CONFIG != null) {
			value = getString(key, FS_CONFIG);
		}
		if (value == null) {
			throw new RuntimeException("Read config failure.");
		}
		return value;
	}

	public static SimpleDateFormat getDefaultFormat() {

		String defaultFormat = getString(Constant.DEFAULT_FORMAT_DATA_TIME);
		SimpleDateFormat sdf = new SimpleDateFormat(defaultFormat);
		return sdf;

	}

	public static Path getBasePath() {
		return Paths.get(Constant.BASE_PATH).normalize();
	}

	public static Path getResultPath() {
		String resultPath = getString(Constant.RESULT_PATH);
		return Paths.get(Constant.BASE_PATH).resolve(resultPath).normalize();
	}

	public static String getMinDate() {
		return getString(Constant.MIN_DATE);
	}

	public static String getMaxDate() {
		return getString(Constant.MAX_DATE);
	}

	public static Path getCommonDataPath() {
		String commonDataPath = getString(Constant.COMMON_DATA_PATH);
		return Paths.get(Constant.BASE_PATH).resolve(commonDataPath).normalize();
	}

	public static String getRawDataFileNamePrefix() {
		return getString(Constant.RAW_DATA_FILENAME);
	}

	public static String getRawDataAvgFileNamePrefix() {
		return getString(Constant.RAW_AVG_FILENAME);
	}

	public static String[] getStationNameArray() {
		return getStringArrayFromConfig(Constant.STATION_NAMES, ",");
	}

	public static SimpleDateFormat getDateFormat() {
		String dateFormat = getString(Constant.DATE_FORMAT);
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf;
	}

	public static String[] getOutputItems() {
		return getStringArrayFromConfig(Constant.OUTPUT_ITEMS, ",");
	}

	public static String[] getFtNames() {
		return getStringArrayFromConfig(Constant.FT_NAMES, ",");
	}

	public static int getFtCount() {
		return Integer.parseInt(getString(Constant.FT_LEN));
	}

	public static double getT0() {
		return Double.parseDouble(getString(Constant.T0));
	}

	public static int getSeriesCount() {
		return Integer.parseInt(getString(Constant.SN));
	}

	public static double getDT() {
		return Double.parseDouble(getString(Constant.DT));
	}

	public static String getStartDate() {
		return getString(Constant.START_TIME);
	}

	public static String getEndDate() {
		return getString(Constant.END_TIME);
	}

	public static Path getComparisonPath() {

		return ConstantHelper.getBasePath().resolve(getString(Constant.COMPARISON_PATH)).normalize();
	}

	public static String getComparisonFilename() {
		return getString(Constant.COMPARISON_FILENAME);
	}

	public static Path getFluxPath() {
		return ConstantHelper.getBasePath().resolve(getString(Constant.FLUX_FILEPATH)).normalize();
	}

	public static String getFuxFilename() {
		return getString(Constant.FLUX_FILENAME);
	}

	public static Path getMakouRawFilePath() {
		return ConstantHelper.getBasePath().resolve(getString(Constant.MAKOU_RAW_FILEPATH)).normalize();
	}
	
	
	///////////////////// oracle ///////////////////
	
	public static String getOracleJDBC() {
		return Constant.ORACLE_JDBC;
	}
	
	public static String getOracleUrl() {
		return Constant.ORACLE_URL;
	}
	
	public static String getOracleUserName() {
		return Constant.USER_NAME;
	}
	
	public static String getOraclePassword() {
		return Constant.PASSWORD;
	}
	
	//////////////////////////// private //////////////////////////

	private static <T extends Properties> String getString(String key, T Props) {

		return Props.getProperty(key);
	}

	private static String[] getStringArrayFromConfig(String key, String regex) {
		String[] outputItems = null;
		String outputItemStr = getString(key);
		if (!StringUtil.isEmpty(outputItemStr)) {
			outputItems = outputItemStr.split(regex);
		}
		return outputItems;
	}

	private static <T extends Properties> T loadProps(T Props, Path ConfigPath) {
		if (ConfigPath.toFile().exists() && ConfigPath.toFile().isFile()) {
			try (InputStream in = new FileInputStream(ConfigPath.toFile());
					InputStreamReader isr = new InputStreamReader(in, "UTF-8");) {
				Props.load(isr);
			} catch (UnsupportedEncodingException e) {
				System.out.println("Only support configuration file format 'UTF-8'");
				throw new RuntimeException(e);
			} catch (IOException e) {
				System.out.println("Read config file failure.");
				throw new RuntimeException(e);
			}
		}
		return Props;
	}

}
